package framework.netty1;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;

import java.nio.charset.StandardCharsets;

/**
 * SimpleChannelInboundHandler；只关注 特定类型的消息，并且希望 Netty 自动释放消息对象。
 * ChannelInboundHandlerAdapter：需要在一个处理器中处理不同类型的消息，需要在处理器中手动管理资源，ReferenceCountUtil.release(Object)
 *  1，ByteBuf 和 其他实现了 ReferenceCounted接口 的引用计数对象，需要手动释放
 *  2，普通的对象（如字符串、整数等）不需要
 */
public class ServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            // 处理收到的数据，并反馈消息到到客户端
            if (msg instanceof String) {
                // 处理 String
                String message = (String) msg;
                System.out.println("Received string message: " + message);
            } else if (msg instanceof ByteBuf) {
                // 处理 ByteBuf 类型
                ByteBuf in = (ByteBuf) msg;
                System.out.println("收到客户端发过来的消息: " + in.toString(StandardCharsets.UTF_8));
            }
        } finally {
            ReferenceCountUtil.release(msg);// 无论处理成功或发生异常，都要释放资源
        }

        // 写入并发送信息到远端（客户端）
        ctx.writeAndFlush(Unpooled.copiedBuffer("你好，我是服务端，我已经收到你发送的消息", StandardCharsets.UTF_8));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 出现异常的时候执行的动作（打印并关闭通道）
        cause.printStackTrace();
        ctx.close();
    }

}
